package com.dogsong.liteflow.editor.config;

import com.dogsong.liteflow.editor.parser.factory.ExpressParserFactory;
import com.dogsong.liteflow.editor.parser.generator.ExpressGenerator;
import com.dogsong.liteflow.editor.service.BizService;
import com.dogsong.liteflow.editor.service.impl.BizServiceImpl;
import com.dogsong.liteflow.editor.service.impl.SqlBizServiceImpl;
import com.yomahub.liteflow.parser.sql.read.SqlReadFactory;
import com.yomahub.liteflow.parser.sql.vo.SQLParserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.ContextRefreshedEvent;

import javax.annotation.Resource;
import java.util.Map;

@Slf4j
@ComponentScan({"com.dogsong.liteflow.editor.parser.el"})
@Configuration
public class LiteFlowEditorAutoConfiguration {

    @Resource
    private final LiteFlowSqlConfig liteFlowSqlConfig;

    public LiteFlowEditorAutoConfiguration(LiteFlowSqlConfig liteFlowSqlConfig) {
        this.liteFlowSqlConfig = liteFlowSqlConfig;
    }

    @ConditionalOnMissingBean(name = {"expressParserFactory"})
    @Bean
    public ExpressParserFactory expressParserFactory(){
        return new ExpressParserFactory();
    }

    @ConditionalOnMissingBean(name = {"expressGenerator"})
    @Bean
    public ExpressGenerator expressGenerator(){
        return new ExpressGenerator();
    }

//    @ConditionalOnBean(name = {"expressGenerator"})
//    @Bean
//    public GenerateELController generateELController(){
//        return new GenerateELController();
//    }

    // ... existing code ...

    @Bean
    public ApplicationListener<ContextRefreshedEvent> liteflowSqlInitializer() {
        return event -> {
            try {
                // 检查是否有SQL配置
                Map<String, Object> extDataMap = liteFlowSqlConfig.getRuleSourceExtDataMap();
                if (extDataMap != null && !extDataMap.isEmpty()) {
                    // 初始化SqlReadFactory
                    SQLParserVO config = new SQLParserVO();
                    // 将配置映射到SQLParserVO对象
                    config.setUrl((String) extDataMap.getOrDefault("url", config.getUrl()));
                    config.setDriverClassName((String) extDataMap.getOrDefault("driverClassName", config.getDriverClassName()));
                    config.setUsername((String) extDataMap.getOrDefault("username", config.getUsername()));
                    config.setPassword(String.valueOf( extDataMap.getOrDefault("password",
                            String.valueOf(config.getPassword()))));
                    config.setApplicationName((String) extDataMap.getOrDefault("applicationName", config.getApplicationName()));

                    // 设置chain表相关配置
                    config.setChainTableName((String) extDataMap.getOrDefault("chainTableName", config.getChainTableName()));
                    config.setChainApplicationNameField((String) extDataMap.getOrDefault("chainApplicationNameField", config.getChainApplicationNameField()));
                    config.setChainNameField((String) extDataMap.getOrDefault("chainNameField", config.getChainNameField()));
                    config.setElDataField((String) extDataMap.getOrDefault("elDataField", config.getElDataField()));
                    config.setChainEnableField((String) extDataMap.getOrDefault("chainEnableField", config.getChainEnableField()));

                    // 设置script表相关配置
                    config.setScriptTableName((String) extDataMap.getOrDefault("scriptTableName", config.getScriptTableName()));
                    config.setScriptApplicationNameField((String) extDataMap.getOrDefault("scriptApplicationNameField", config.getScriptApplicationNameField()));
                    config.setScriptIdField((String) extDataMap.getOrDefault("scriptIdField", config.getScriptIdField()));
                    config.setScriptNameField((String) extDataMap.getOrDefault("scriptNameField", config.getScriptNameField()));
                    config.setScriptDataField((String) extDataMap.getOrDefault("scriptDataField", config.getScriptDataField()));
                    config.setScriptTypeField((String) extDataMap.getOrDefault("scriptTypeField", config.getScriptTypeField()));
                    config.setScriptLanguageField((String) extDataMap.getOrDefault("scriptLanguageField", config.getScriptLanguageField()));
                    config.setScriptEnableField((String) extDataMap.getOrDefault("scriptEnableField", config.getScriptEnableField()));

                    // 设置其他配置
                    config.setRouteField((String) extDataMap.getOrDefault("routeField", config.getRouteField()));
                    config.setNamespaceField((String) extDataMap.getOrDefault("namespaceField", config.getNamespaceField()));
                    config.setChainCustomSql((String) extDataMap.getOrDefault("chainCustomSql", config.getChainCustomSql()));
                    config.setScriptCustomSql((String) extDataMap.getOrDefault("scriptCustomSql", config.getScriptCustomSql()));

                    // 设置日志和轮询配置
                    config.setPollingIntervalSeconds((Integer) extDataMap.getOrDefault("pollingIntervalSeconds", config.getPollingIntervalSeconds()));
                    config.setPollingStartSeconds((Integer) extDataMap.getOrDefault("pollingStartSeconds", config.getPollingStartSeconds()));

                    log.info("LiteFlow SQL配置: url={}, username={}, chainTableName={}",
                            config.getUrl(), config.getUsername(), config.getChainTableName());

                    // 注册配置
                    SqlReadFactory.registerRead(config);
                }
            } catch (Exception e) {
                // 记录初始化异常
                log.error("LiteFlow SQL初始化异常", e);
            }
        };
    }

// ... existing code ...


    @Bean("sqlBizService")
    public BizService sqlBizService(){
        return new SqlBizServiceImpl();
    }

    @ConditionalOnMissingBean(value = {BizService.class})
    @Bean
    public BizService defaultBizService(){
        return new BizServiceImpl();
    }

//    @ConditionalOnBean(value = {BizService.class})
//    @Bean
//    public BizController bizController(){
//        return new BizController();
//    }
}
